/*
 * common.h
 *
 *  Created on: Dec 6, 2008
 *      Author: michael
 */

#ifndef COM_H_
#define COM_H_

#include<unistd.h>
#include<string.h>
#include<stdlib.h>
#include<stdio.h>
#include<stdarg.h>
#include<errno.h>
#include<time.h>
#include<ctype.h>
#include<utmpx.h>
#include<sys/types.h>
#include<sys/time.h>
#include<sys/msg.h>
#include<sys/sem.h>
#include<sys/socket.h>
#include<sys/signal.h>
#include<netdb.h>
#include<netinet/in.h>

#ifndef NULL
#define NULL 0
#endif

#ifndef TRUE
#define TRUE 1
#endif

#ifndef FALSE
#define FALSE 0
#endif

#define MAXBUF 4096

/* the output log file*/
#ifndef TRACE_FILE
#define TRACE_FILE "./trace.log"
#endif

#ifndef min
#define min(A,B) ((A)<(B)?(A):(B))
#endif

#ifndef max
#define max(A,B) ((A)>(B)?(A):(B))
#endif

#define minsize(A,B) (sizeof(A)<sizeof(B)?sizeof(A):sizeof(B))
#define maxsize(A,B) (sizeof(A)>sizeof(B)?sizeof(A):sizeof(B))

#ifndef isblank
#define isblank(c) ((c)==' '||(c)=='\t' || (c) == '\n' || (c) == '\r')
#endif

#ifndef isdigit
#define isdigit(c) ((c)<='9' && (c)>='0')
#endif

#ifndef isalpha
#define isalpha(c) ((c)<='z' && (c) >='a' || (c) <='Z' && (c) >= 'A')
#endif

#ifndef upper
#define upper(c) ((c)<='z' && (c)>='a' ? (c)-'a'+'A':(c))
#endif

#ifndef lower
#define lower(c) ((c)<='Z' && (c)>='A'?(c)-'A'+'a':(c))
#endif

/* Debug Lib */
#define VERIFY(b) Verify((errno=0)||(b),NULL,__FILE__,__LINE__)
#define ASSERT(b) if(VERIFY(b));else return -1;
#define ASSERTEXT(b,c) if(VERIFY(b));else return c;

int Verify(int bStatus, const char *pszInfo, const char *pszFile, int nLine);
int Log(FILE *pFile, const char * pformat, ...);
int Trace(const char *pformat, ...);
int HexLog(FILE *pFile, void *pData, int nSize);
int HexTrace(void *pData, int nSize);

/* File Lib */
int ReadFile(int nFile, void *pData, int *pSize);
int WriteFile(int nFile, void *pData, int nSize);
int ReadFileTime(int nFile, void *pData, int *pnSize, int nTimeout);
int WriteFileTime(int nFile, void *pData, int nSize, int nTimeout);

/* Msg Queue Lib*/
/****
 * type logic msg group
 * */
int ReadMsg(int msgid, void *pText, int *pSize, int *pType);
int WriteMsg(int msgid, void *pText, int nSize, int nType);
int ReadMsgExt(int msgid, void *pText, int *pSize, int *pType, int nTimeout);
int WriteMsgExt(int msgid, void *pText, int nSize, int nType, int nTimeout);

/* Sem Lib sem is a sem array, inIndex indicate the sem in the array*/
int Semop(int semid, int nIndex, int nVal);
int SemopNowait(int semid, int nIndex, int nVal);
int SemopTime(int semid, int nIndex, int nVal, int nTimeout);

#define SEMP(semid,nIndex) Semop(semid,nIndex,-1);
#define SEMV(semid,nIndex) Semop(semid,nIndex,1);
#define SEMZ(semid,nIndex) Semop(semid,nIndex,0);
#define SEMPNW(semid,nIndex) SemopNowait(semid,nIndex,-1);
#define SEMVNW(semid,nIndex) SemopNowait(semid,nIndex,1);
#define SEMZNW(semid,nIndex) SemopNowait(semid,nIndex,0);
#define SEMPT(semid, nIndex, nTime) SemopTime(semid, nIndex , -1, nTime)
#define SEMVT(semid, nIndex, nTime) SemopTime(semid, nIndex , 1, nTime)
#define SEMZT(semid, nIndex, nTime) SemopTime(semid, nIndex , 0, nTime)

/****
 * shm 1-n-n model
 * shmid
 * index the count of the mem block
 * size the size of the each mem block
 * set the info area and init the MAP area
 * */
int CreateMemo(int shmid, int index, int size);
/****
 * alloc a mem block from shm and return back the block index by *index
 * */
int AllocMemo(int shmid, int semid, int semindex, int *index);
/****
 * find the free block from the MAP area and return the index.
 * */
int AllocMemoExt(char *pc, int *index);
/****
 * free the shm of the index block mem
 * */
void FreeMemo(int shmid, int semid, int semindex, int index);
/****
 * get the addr of the index block mem in the shm
 * */
char *GetMemoAddr(char *paddr, int index);

/****
 * background process
 * */
int InitServer();

typedef struct structTIMESTRU
{
	int nY;
	int nM;
	int nD;
	int nH;
	int nMin;
	int nS;
} TIMESTRU;

typedef TIMESTRU *pTIME;

TIMESTRU GetTime();

TIMESTRU GetOffsetTime(TIMESTRU time, int nOffset);

/****
 * TCP Lib
 * */
int CreateSock(int *pSock, int nPort, int nMaxConnect);
int AcceptSock(int *pSock, int nSock);
int ConnectSock(int *pSock, int nPort, char *szAddr/*ip str*/);
int LocateRemoteAddr(int nSock, char *szAddr);
int LocateLocalAddr(int nSock, char *szAddr);

/****
 * UDP Lib
 * */
int CreateUdpSock(int *pSock, int nPort);
int SendMsgByUdp(void *pMsg, int nSize, char *szAddr, int nPort);
int RecvMsgByUdp(int nSock, void *pData, int *pSize);

/****
 * String packet struct
 * */
#define STRSTR 0
#define STRINT 1
#define STRFLOAT 2
#define STRDOUBLE 3

typedef struct STRPACKETSTRU
{
	int nAmount;//total fields
	int nFlag;//0:fixed lenght field,1:separator field
	int *pFieldlen;// field length
	int nSeparatorlen;
	char cSeparator[10];//separator char array
	char *fieldaddr[];// pointer to each field
} STRPACKET;
typedef STRPACKET *PSTRPACKET;

char *TrimString(char *pStr);
int strrespre(char *buf, PSTRPACKET pStrpack);
int
		strresvalue(char *buf, STRPACKET strpack, int nIndex, void *pVal,
				int nType);
int GetConfigValue(char *szPath, char *szRoot, char *szName, void *pVal,
		int nType);
#endif /* COM_H_ */
